package alipay.openplatform.edu.campus.jiuye.api.controller.user;

import alipay.openplatform.edu.campus.jiuye.alipay.api.domain.StudentInfoQueryDomain;
import alipay.openplatform.edu.campus.jiuye.alipay.api.iservice.IAlipayLocator;
import alipay.openplatform.edu.campus.jiuye.alipay.api.utils.AlipayUtils;
import alipay.openplatform.edu.campus.jiuye.alipay.api.utils.StringUtils;
import alipay.openplatform.edu.campus.jiuye.api.utils.ContextUtils;
import alipay.openplatform.edu.campus.jiuye.common.cache.CacheManagerService;
import alipay.openplatform.edu.campus.jiuye.common.enums.ResultCode;
import alipay.openplatform.edu.campus.jiuye.common.utils.CRequestUtil;
import alipay.openplatform.edu.campus.jiuye.common.utils.ObjectUtils;
import alipay.openplatform.edu.campus.jiuye.model.vo.BllTopicUserVO;
import alipay.openplatform.edu.campus.jiuye.model.vo.UserBaseInfo;
import alipay.openplatform.edu.campus.jiuye.service.dao.ApiResult;
import alipay.openplatform.edu.campus.jiuye.service.iservice.activity.IBllGoodVoiceUserService;
import alipay.openplatform.edu.campus.jiuye.service.iservice.business.IBllTopicUserService;
import alipay.openplatform.edu.campus.jiuye.service.iservice.system.ISchoolInfoService;
import alipay.openplatform.edu.campus.jiuye.service.iservice.user.IUserInfoService;
import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserUserinfoShareResponse;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RequestMapping(value = "/jiuye/api")
@Controller
public class UserInfoController {
    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private CacheManagerService cacheManagerService;

    @Autowired
    private IAlipayLocator alipayLocator;

    @Autowired
    private ISchoolInfoService schoolInfoService;

    @Autowired
    IBllGoodVoiceUserService bllGoodVoiceUserService;

    private static final Logger logger = LoggerFactory.getLogger(UserInfoController.class);

    @ResponseBody
    @RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
    public ApiResult getUserInfo() {
        String userId = ContextUtils.getUserId(request);
        logger.info("从Session中获取的userId={}", userId);
        if (StringUtils.isBlank(userId)) {
            return ApiResult.build(ResultCode.AUTH_UNAUTHORIZED.getCode(), ResultCode.AUTH_UNAUTHORIZED.getName());
        }
        try {
            UserBaseInfo userBaseInfo = getUserInfoByUserId(userId);
            if (ObjectUtils.isNotNull(userBaseInfo)) {
                return ApiResult.buildSuccess("0", "获取用户信息成功!", userBaseInfo);
            } else {
                return ApiResult.build("-1", "获取用户信息失败");
            }
        } catch (Exception e) {
            logger.error("获取用户信息失败|UserInfoController|getUserInfo|params:message={}", e);
            return ApiResult.build(ResultCode.SYSTEM_EXCEIPTION.getCode(), ResultCode.SYSTEM_EXCEIPTION.getName());
        }
    }

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public ModelAndView index() {
        return new ModelAndView("front/index");
    }


    /**
     * 授权登录
     *
     * @param authCode
     * @return
     */
    @RequestMapping(value = "/user/auth", method = RequestMethod.GET)
    public ModelAndView getAuthEntryIndex1(@RequestParam(value = "auth_code",required = false) String authCode, @RequestParam(value = "state", required = false) String state) {


        request.getSession().setAttribute(ContextUtils.SESSIONUTILS, "2088012199249492");

        if(state != null && !state.equals("")) {

            state = state.replaceAll("_", "&");
            return getModelAndView("locator", state);
        }

        return new ModelAndView("front/index");//正常登录
    }


    /**
     * 授权登录
     *
     * @param authCode
     * @return
     */
    @RequestMapping(value = "/user/auth1", method = RequestMethod.GET)
    public ModelAndView getAuthEntryIndex(@RequestParam(value = "auth_code") String authCode, @RequestParam(value = "state", required = false) String state) {


        String userId = ContextUtils.getUserId(request);
       // String userId = "2088512231539890";
        logger.info("从Session中获取的userId={}", userId);

        //1.授权
        AlipaySystemOauthTokenResponse userAuth = null;
        try {
            userAuth = alipayLocator.getUserAuth(authCode);
            if (userAuth == null) {
                logger.error("获取用户授权结果失败");
                return getModelAndView("front/error", "授权失败!");
            }
            //授权码过期
            if (!AlipayUtils.checkIsAuthValid(userAuth)) {
                //session不过期
                if (userId != null) {
                    //检测是否需要更新用户信息
                    UserBaseInfo userBaseInfo = getUserInfoByUserId(userId);
                    if (ObjectUtils.isNotNull(userBaseInfo)) {
                        Integer date = Integer.parseInt(getVersion());
                        Integer version = Integer.parseInt(userBaseInfo.getVersion() == null ? "0" : userBaseInfo.getVersion());
                        if (date - version >= 30 && StringUtils.isBlank(state)) {
                            logger.error("需要更新用户信息,授权码无效,重新授权登录");
                            //授权码无效,重新授权登录
                            return new ModelAndView("go");
                        } else {
                            if (StringUtils.isNotBlank(state)) {
                                logger.info("扫码进入指定页,授权码无效,session不过期,跳转,state={}", state);
                                state = state.replaceAll("_", "&");
                                return getModelAndView("locator", state);
                            } else {
                                logger.info("不需要更新用户信息,授权码无效,session不过期,正常登录");
                                return new ModelAndView("locator");//正常登录
                            }
                        }
                    } else {
                        logger.error("授权码过期,session不过期,但是用户不存在");
                        return getModelAndView("front/error", "用户信息异常,请重新登录!");
                    }
                } else {
                    logger.error("授权码过期,session过期");
                    return getModelAndView("front/error", "授权码无效,请重新登录!");
                }
            }
        } catch (Exception e) {
            return getModelAndView("front/error", "系统异常,请重新登录!");
        }

        //授权码不过期
        String accessToken = userAuth.getAccessToken();
        String uid = userAuth.getUserId();

        //session不过期,用户授权成功,当前登录用户是否同一人,是同一人直接返回当前授权登录.
        if (userId != null && uid.equals(userId)) {
            //检查用户信息是否存在
            UserBaseInfo userBaseInfo = null;
            try {
                userBaseInfo = getUserInfoByUserId(userId);
                if (ObjectUtils.isNull(userBaseInfo)) {
                    return getModelAndView("front/error", "用户信息异常,请重新登录!");
                }
            } catch (Exception e) {
                return getModelAndView("front/error", "系统异常,请重新登录!");
            }

            if (StringUtils.isNotBlank(state)) {
                logger.info("扫码进入指定页,授权码不过期,session不过期,当前用户是同一个人,跳转,state={}", state);
                state = state.replaceAll("_", "&");
                return getModelAndView("locator", state);
            } else {
                //检查是否需要更新用户信息
                boolean isNeedUpdate = checkIsNeedUpdateUserInfo(userBaseInfo);
                //如果需要
                if (isNeedUpdate) {
                    //修改用户信息
                    ModelAndView mv = updateUserInfo(userId, accessToken);
                    if (ObjectUtils.isNotNull(mv)) return mv;
                }
                logger.info("不需要更新用户信息,授权码不过期,session不过期,当前用户是同一个人,正常登录");
                return new ModelAndView("locator");
            }
        }

        //授权码不过期,session过期,使用uid
        //检查是否为已注册用户
        UserBaseInfo userBaseInfo = null;
        try {
            userBaseInfo = getUserInfoByUserId(uid);
        } catch (Exception e) {
            return getModelAndView("front/error", "系统异常,请重新登录!");
        }

        //老用户
        if (ObjectUtils.isNotNull(userBaseInfo)) {
            if (StringUtils.isNotBlank(state)) {
                logger.info("扫码进入指定页,授权码不过期,session过期,设置session={},跳转,state={}", uid, state);
                request.getSession().setAttribute(ContextUtils.SESSIONUTILS, uid);
                state = state.replaceAll("_", "&");
                return getModelAndView("locator", state);
            } else {
                //检查是否需要更新用户信息
                boolean isNeedUpdate = checkIsNeedUpdateUserInfo(userBaseInfo);
                //如果需要
                if (isNeedUpdate) {
                    //修改用户信息
                    ModelAndView mv = updateUserInfo(uid, accessToken);
                    if (ObjectUtils.isNotNull(mv)) return mv;
                }
                request.getSession().setAttribute(ContextUtils.SESSIONUTILS, uid);
                logger.info("不需要修改用户信息,且当前用户是老用户,直接登录");
                return new ModelAndView("locator");//登录
            }
        }

        //新用户
        //2.获取用户信息
        AlipayUserUserinfoShareResponse userinfo
                = alipayLocator.getUserInfo(accessToken);

        if (ObjectUtils.isNull(userinfo)) {
            return getModelAndView("front/error", "未能从支付宝获得用户信息!");
        }

        if (!AlipayUtils.IsCertified(userinfo)) {
            return getModelAndView("front/error", "未在支付宝实名认证!");
        }

        userBaseInfo = new UserBaseInfo();
        userBaseInfo.setUserId(uid);
        userBaseInfo.setName(userinfo.getRealName());
        userBaseInfo.setCreatetime(new Date());
        userBaseInfo.setIfDel(Boolean.FALSE);
        userBaseInfo.setImgUrl(userinfo.getAvatar());

        //是否手机认证
        if (AlipayUtils.IsMobileCertified(userinfo)) {
            userBaseInfo.setMobile(userinfo.getMobile());
        } else {
            userBaseInfo.setMobile(null);
        }

        //是否进行过学籍认证
        if (AlipayUtils.IsStudentCertified(userinfo)) {
            //3.获取学生信息
//            StudentInfo studentInfo
//                    = alipayLocator.getStudentInfo(accessToken);
            StudentInfoQueryDomain studentInfoQueryDomain
                    = alipayLocator.queryStudentInfoByAccessToken(accessToken);
            if (studentInfoQueryDomain == null) {
                return getModelAndView("front/error", "获取学历信息失败!");
            }

            //学籍认证用户
//            userBaseInfo.setSchoolName(studentInfo.getCollegeName());
//            userBaseInfo.setDegree(studentInfo.getDegree());
//            userBaseInfo.setSchoolId(studentInfo.getCollegeNo());
//            userBaseInfo.setCityId(studentInfo.getCityNo());
            userBaseInfo.setSchoolName(studentInfoQueryDomain.getCampusName());
            userBaseInfo.setDegree(studentInfoQueryDomain.getDegree());
            String campusCode = studentInfoQueryDomain.getCampusCode();
            userBaseInfo.setSchoolId(campusCode);
            Long cityId = new Long(0);
            try {
                cityId = schoolInfoService.getCityIdBySchoolId(campusCode);
            } catch (Exception e) {
                logger.error("授权|通过学校id获取城市id出错");
                e.printStackTrace();
            }
            userBaseInfo.setCityId(Long.toString(cityId == null ? 0 : cityId));

        } else {
            //没有学籍认证用户
            userBaseInfo.setSchoolName("未知");
            userBaseInfo.setDegree("未知");
            userBaseInfo.setSchoolId("0");
            userBaseInfo.setCityId("0");
        }

        userBaseInfo.setVersion(getVersion());

        //添加用户信息
        if (userInfoService.saveUserInfo(userBaseInfo) > 0) {
            cacheManagerService.setObject(uid, userBaseInfo);
        }

        //登录
        request.getSession().setAttribute(ContextUtils.SESSIONUTILS, uid);

        if (StringUtils.isNotBlank(state)) {
            logger.info("扫码进入指定页,授权码不过期,新用户注册成功,跳转,state={}", state);
            state = state.replaceAll("_", "&");
            return getModelAndView("locator", state);
        } else {
            logger.info("普通方式登录,授权码不过期,新用户注册成功,跳转");
            return new ModelAndView("locator");
        }
    }

    /**
     * 获取用户信息
     *
     * @param userId
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private UserBaseInfo getUserInfoByUserId(String userId) throws InvocationTargetException, IllegalAccessException {
        return userInfoService.getUserInfoByUserId(userId);
    }

    /**
     * 获取最新版本号
     *
     * @return
     */
    private static String getVersion() {
        return new DateTime().toString("yyyyMMdd");
    }

    /**
     * 更新用户信息
     *
     * @param userId
     * @param accessToken
     * @return
     */
    private ModelAndView updateUserInfo(String userId, String accessToken) {
        Map map = new HashMap();
        //获取用户信息
        AlipayUserUserinfoShareResponse userinfo
                = alipayLocator.getUserInfo(accessToken);

        if (ObjectUtils.isNull(userinfo)) {
            return getModelAndView("front/error", "未能从支付宝获得用户信息!");
        }

        map.put("userId", userId);
        map.put("imgUrl", userinfo.getAvatar());

        //是否手机认证
        if (AlipayUtils.IsMobileCertified(userinfo)) {
            map.put("mobile", userinfo.getMobile());
        } else {
            map.put("mobile", null);
        }

        //是否进行过学籍认证
        if (AlipayUtils.IsStudentCertified(userinfo)) {
//            StudentInfo studentInfo
//                    = alipayLocator.getStudentInfo(accessToken);
//            if (studentInfo == null) {
//                return getModelAndView("front/error", "获取学历信息失败!");
//            }
            StudentInfoQueryDomain studentInfoQueryDomain
                    = alipayLocator.queryStudentInfoByAccessToken(accessToken);
            if (studentInfoQueryDomain == null) {
                return getModelAndView("front/error", "获取学历信息失败!");
            }
            String campusCode = studentInfoQueryDomain.getCampusCode();
            Long cityId = new Long(0);
            try {
                cityId = schoolInfoService.getCityIdBySchoolId(campusCode);
            } catch (Exception e) {
                logger.error("授权|通过学校id获取城市id出错");
                e.printStackTrace();
            }
            map.put("schoolId", studentInfoQueryDomain.getCampusCode());
            map.put("schoolName", studentInfoQueryDomain.getCampusName());
            map.put("degree", studentInfoQueryDomain.getDegree());
            map.put("cityId", cityId == null ? 0 : cityId);
        } else {
            map.put("schoolId", "0");
            map.put("schoolName", "未知");
            map.put("degree", "未知");
            map.put("cityId", "0");
        }
        map.put("version", getVersion());

        //修改用户信息
        if (userInfoService.updateUserBaseInfo(map) > 0) {
            logger.info("更新用户信息成功,新信息为:{}", JSON.toJSONString(map));
            //修改用户信息成功,清除缓存
            cacheManagerService.del(userId);
        }
        return null;
    }

    @Autowired
    IBllTopicUserService iBllTopicUserService;

    /**
     * 执行扫码后记录用户的扫码记录
     *
     * @param viewName 视图名称
     * @param message  返回消息
     * @return
     */
    private void DoUserMa(String viewName, String message) {
        try {
            if (viewName.equals("locator") && !message.equals("")) {
                Map<String, String> mapRequest = CRequestUtil.URLRequest(message);
                if (mapRequest != null || mapRequest.size() > 0) {
                    String isMa = mapRequest.get("isma");
                    if (isMa != null && isMa.equals("1")) {
                        String cityId = mapRequest.get("cityid");
                        String schoolId = mapRequest.get("schoolid");
                        String topicId = mapRequest.get("topicid");

                        cityId = cityId == null ? "0" : cityId;
                        cityId = cityId.equals("") ? "0" : cityId;
                        schoolId = schoolId == null ? "0" : schoolId;
                        schoolId = schoolId.equals("") ? "0" : schoolId;
                        String userId = ContextUtils.getUserId(request);
                        userId = userId == null ? "" : userId;

                        BllTopicUserVO vo = new BllTopicUserVO();
                        vo.setCityId(Integer.parseInt(cityId));
                        vo.setSchoolId(Integer.parseInt(schoolId));
                        vo.setTopicId(Integer.parseInt(topicId));
                        vo.setUserId(userId);

                        logger.info("cityId:" + cityId + ",schoolId:" + schoolId + ",topicId:" + topicId);
                        iBllTopicUserService.addBllTopicUser(vo);
                    }

                    String isActivityQRCode = mapRequest.get("isactivityqrcode");
                    if (isActivityQRCode != null && isActivityQRCode.equals("1")) {
                        String userId = ContextUtils.getUserId(request);
                        //活动扫码次数+1
                        bllGoodVoiceUserService.scanTimes();
                        logger.info("活动扫码次数+1");
                        //活动扫码人数+1
                        if (!cacheManagerService.sismember("user_times", userId)) {
                            cacheManagerService.sadd("user_times", userId);
                            bllGoodVoiceUserService.scanUserTimes();
                            logger.info("活动扫码人数+1");
                        }
                    }

                }
            }
        } catch (Exception err) {
            logger.info(err.getMessage());
        }
    }

    /**
     * @param viewName 视图名称
     * @param message  返回消息
     * @return
     */
    private ModelAndView getModelAndView(String viewName, String message) {

        //扫码后收集用户的扫码记录
        DoUserMa(viewName, message);

        ModelAndView mv = new ModelAndView(viewName);
//        mv.addObject("code", "-1");
        mv.addObject("message", message);
        return mv;
    }

    /**
     * @param viewName 视图名称
     * @param code     返回码
     * @param message  返回消息
     * @return
     */
    private static ModelAndView getModelAndView(String viewName, String code, String message) {
        ModelAndView mv = new ModelAndView(viewName);
        mv.addObject("code", code);
        mv.addObject("message", message);
        return mv;
    }


    /**
     * 是否需要更新用户信息
     *
     * @param userBaseInfo
     * @return true 需要,false不需要
     */
    private static boolean checkIsNeedUpdateUserInfo(UserBaseInfo userBaseInfo) {
        Integer date = Integer.parseInt(getVersion());
        Integer version = Integer.parseInt(StringUtils.isBlank(userBaseInfo.getVersion()) ? "0" : userBaseInfo.getVersion());
        if (date - version >= 30) {
            return true;
        } else {
            return false;
        }
    }

}